package com.itheima.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.itheima.article.feign.ApArticleFeign;
import com.itheima.common.constants.SystemConstants;
import com.itheima.common.enums.HttpCodeEnum;
import com.itheima.common.exception.LeadNewsException;
import com.itheima.common.util.AppJwtUtil;
import com.itheima.common.util.RequestContextUtil;
import com.itheima.common.vo.ResultVo;
import com.itheima.user.dto.LoginDto;
import com.itheima.user.dto.UserRelationDto;
import com.itheima.user.mapper.ApUserFanMapper;
import com.itheima.user.mapper.ApUserFollowMapper;
import com.itheima.user.pojo.ApUser;
import com.itheima.user.mapper.ApUserMapper;
import com.itheima.user.pojo.ApUserFan;
import com.itheima.user.pojo.ApUserFollow;
import com.itheima.user.service.ApUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

/**
 * @description <p>APP用户信息 业务实现</p>
 *
 * @version 1.0
 * @package com.itheima.user.service.impl
 */
@Service
public class ApUserServiceImpl extends ServiceImpl<ApUserMapper, ApUser> implements ApUserService {

    @Autowired
    private ApUserFollowMapper apUserFollowMapper;

    @Autowired
    private ApArticleFeign apArticleFeign;

    @Autowired
    private ApUserFanMapper apUserFanMapper;

    /**
     * 登录校验
     * @param dto
     * @return
     */
    @Override
    public Map<String, Object> login(LoginDto dto) {
        if (null == dto){
            throw new LeadNewsException(HttpCodeEnum.PARAM_REQUIRE);
        }
        //手机号码
        String phone = dto.getPhone();
        //登录密码
        String password = dto.getPassword();
        Map<String,Object> map = new HashMap<>();

        //判断是否为匿名登录
        if (StringUtils.isEmpty(password)&&StringUtils.isEmpty(phone)) {
            //如果是则id为0
            String token = AppJwtUtil.createToken(SystemConstants.ANONYMOUS_USER_ID);
            map.put("token",token);
        }else {
            //如果不是查询用户
            ApUser apUser = query().eq("phone", dto.getPhone()).one();
            if (null == apUser){
                throw new LeadNewsException("密码或手机号不正确");
            }
            //密码加盐加密
            String digest = DigestUtils.md5DigestAsHex((password += apUser.getSalt()).getBytes());
            //比较加盐加密的密码和数据库的密码
            if (!digest.equals(apUser.getPassword())){
                throw new LeadNewsException("手机号或密码错误");
            }
            //创建token
            String token = AppJwtUtil.createToken(apUser.getId().longValue());
            //设置敏感词
            apUser.setPassword(null);
            apUser.setSalt(null);
            map.put("token",token);
            map.put("user", JSON.toJSONString(apUser));
        }
        //返回
        return map;


    }

    /**
     * 关注作者与取消关注
     * @param dto
     */
    @Override
    @Transactional
    public void userFollow(UserRelationDto dto) {
       //1.判断是否为匿名
        if (RequestContextUtil.isAnonymous()){
            throw new LeadNewsException(HttpCodeEnum.NEED_LOGIN);
        }
        Long authorId = dto.getAuthorId();
        Long userId = Long.parseLong(RequestContextUtil.getUserId());
        //2.判断关注还是取消关注
        ApUserFollow apUserFollow = getUserFollowRecord(userId,authorId);
        if (dto.getOperation() == 0){
            //3.关注行为
            //3.1查询是否已关注
            if (null != apUserFollow){
                throw new   LeadNewsException("已经关注过了");
            }
            //3.2不存在则添加记录，添加粉丝记录
            addApUserFollow(dto);
            addUserFan(userId,authorId);
        }else {
            //4.取消关系行为
            //4.1查询是否已关注，未关注报错
            if (null == apUserFollow){
                throw new LeadNewsException("还没有关注作者");
            }
            //4.2存在则删除关注记录和粉丝记录
            deleteUserFollow(userId,authorId);
            deleteUserFan(userId,authorId);
        }

    }

    /**
     * 删除粉丝记录
     * @param userId
     * @param articleId
     */
    private void deleteUserFan(Long userId, Long articleId) {
        LambdaQueryWrapper<ApUserFan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ApUserFan::getUserId,userId);
        wrapper.eq(ApUserFan::getFansId,articleId);
        apUserFanMapper.delete(wrapper);
    }

    /**
     * 删除关注记录
     * @param userId
     * @param articleId
     */
    private void deleteUserFollow(Long userId, Long articleId) {
        LambdaQueryWrapper<ApUserFollow> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ApUserFollow::getUserId,userId);
        wrapper.eq(ApUserFollow::getFollowId,articleId);
        apUserFollowMapper.delete(wrapper);
    }

    /**
     * 添加粉丝记录
     * @param userId
     * @param articleId
     */
    private void addUserFan(Long userId, Long articleId) {
        ApUserFan apUserFan = new ApUserFan();
        apUserFan.setIsShieldComment(0);//不屏蔽
        apUserFan.setIsShieldLetter(0);//不屏蔽
        apUserFan.setIsDisplay(1);//允许
        apUserFan.setCreatedTime(LocalDateTime.now());
        apUserFan.setLevel(0);
        ApUser apUser = getById(userId);
        apUserFan.setFansName(apUser.getName());
        apUserFan.setFansId(userId);
        apUserFan.setUserId(articleId);
        apUserFanMapper.insert(apUserFan);
    }

    /**
     * 添加关注记录
     * @param dto
     */
    private void addApUserFollow(UserRelationDto dto) {
        ApUserFollow apUserFollow = new ApUserFollow();
        apUserFollow.setCreatedTime(LocalDateTime.now());
        apUserFollow.setIsNotice(1);
        apUserFollow.setLevel(0);
        apUserFollow.setFollowId(dto.getAuthorId());
        //远程调用文章微服务查询作者名称
        ResultVo<String> authorNameResult = apArticleFeign.getAuthorName(dto.getArticleId());
        if (!authorNameResult.isSuccess()){
            throw new LeadNewsException("操作失败，请重试");
        }
        String authorName = authorNameResult.getData();
        apUserFollow.setFollowName(authorName);
        apUserFollow.setUserId(Long.parseLong(RequestContextUtil.getUserId()));
        apUserFollowMapper.insert(apUserFollow);
    }

    private ApUserFollow getUserFollowRecord(Long userId, Long articleId) {
        LambdaQueryWrapper<ApUserFollow> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ApUserFollow::getUserId,userId);
        wrapper.eq(ApUserFollow::getFollowId,articleId);
        return apUserFollowMapper.selectOne(wrapper);
    }
}
